Billboard Top 100 Song Length Over Time

library(ggplot2)
library(plotly)
library(dplyr)

# Your ggplot base
plot <- spotify_cleaned_all %>% 
  filter(duration_sec <= 600, date>= '1958-08-06') %>% 
  ggplot(aes(
    x = as.Date(date),
    y = duration_sec,
    text = paste0(
      "Song: ", song, "<br>",
      "Artist: ", artist, "<br>",
      "Date: ", date, "<br>",
      "Duration: ", duration_min
    ),
    group = 1
  )) +
  geom_jitter(color = "darkgreen", size = 1.5, alpha = 0.4, width = 10) +
  geom_smooth(method = "gam", color = "darkblue", se = FALSE, linewidth = 1.2) +
  scale_y_continuous(
    name = "Song Duration",
    breaks = seq(0, 600, by = 60),
    labels = function(x) sprintf("%d:%02d", floor(x / 60), round(x %% 60))
  ) +
  labs(
    title = "Billboard Hot 100 Top 10 Song Durations Over Time",
    x = "Chart Date"
  ) +
  theme_minimal()


p <- ggplotly(plot + labs(title = NULL), tooltip = "text")  # remove ggplot title
## Warning: The following aesthetics were dropped during statistical transformation: text
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?
p <- layout(p,
  title = NULL,  # make sure nothing else forces the title
  images = list(
    list(
      source = billboard_b64,
      xref = "paper", yref = "paper",
      x = 0.7, y = 1.04,
      sizex = 0.12, sizey = 0.12,
      xanchor = "left", yanchor = "top"
    ),
    list(
      source = spotify_b64,
      xref = "paper", yref = "paper",
      x = 0.85, y = 1.05,
      sizex = 0.12, sizey = 0.12,
      xanchor = "left", yanchor = "top"
    )
  ),
  annotations = list(
    list(  # Title text aligned with logos
      text = "<b>Billboard Hot 100 Top 10 Song Durations Over Time</b>",
      x = 0.34, y = 1.045,
      xref = "paper", yref = "paper",
      xanchor = "center", yanchor = "top",
      showarrow = FALSE,
      font = list(size = 16, color = "black")
    ),
    list(  # Data source footnote
      text = "Data sources: Spotify Web API & Billboard Hot 100",
      x = 0.05, y = 0.01,
      xref = "paper", yref = "paper",
      xanchor = "left", yanchor = "bottom",
      showarrow = FALSE,
      font = list(size = 10, color = "gray40")
    )
  ),
  margin = list(t = 100)  # top margin to fit title
)


p